<script>
import { getDictByType } from '@/api/config_platform.js'
import { deepClone, treeToList } from '@/utils'
import { mapGetters } from 'vuex'
import { getDistrictTree } from '@/api/system.js'
import { getSceneList } from '@/api/preview.js'
function deepTree(tree, id = 'id') {
  tree.forEach((t) => {
    t.label = t.name || t.text
    t.value = t[id]
    if (t.childNode && t.childNode.length > 0) {
      t.children = t.childNode
      deepTree(t.children, id)
    }
  })
}
export default {
  name: 'AddForm',
  data() {
    const { districtName, districtNo, poltype, districtId } =
      this.$store.getters.user
    const getDefualtForm = () => {
      return {
        itemSceneId: '', // 场景分类id
        itemSceneName: '',
        itemCode: '',
        itemName: '',
        fromCode: '1',
        descriptions: '',
        categoryCode: '',
        categoryId: '',
        belongStratumCode: String(poltype),
        belongStratumName: '', // 根据所属层级code相对应
        levelCode: '1',
        adviceDisposeDept: '', // 建议部门
        fromUnitCode: '',
        pursuantShortName: '',
        pursuantFullName: '',
        toCode: '1',
        toName: '',
        areaName: districtName, // 用户地区名称
        areaCode: districtNo, // 用户地区Id
        districtId: districtId,
        fileList: []
      }
    }
    return {
      categoryList: [],
      originForm: {
        model: getDefualtForm()
      },
      addForm: {
        model: getDefualtForm(),
        rules: {
          itemCode: [
            {
              required: true,
              message: '请输入事项编码',
              trigger: 'submit'
            },
            {
              type: 'string',
              max: 50,
              message: '长度50字符以内',
              trigger: 'change'
            }
          ],
          itemName: [
            {
              required: true,
              message: '请输入事项名称',
              trigger: 'submit'
            },
            { max: 50, message: '长度50字符以内', trigger: 'change' }
          ],
          fromCode: [
            {
              required: true,
              message: '请选择',
              trigger: 'submit'
            }
          ],
          descriptions: [
            {
              required: true,
              message: '请输入事项描述',
              trigger: 'submit'
            },
            { max: 1000, message: '长度1000字符以内', trigger: 'change' }
          ],
          categoryCode: [
            {
              required: true,
              message: '请选择',
              trigger: 'submit'
            }
          ],
          itemSceneId: [
            {
              required: true,
              message: '请选择多跨场景',
              trigger: 'submit'
            }
          ],
          categoryId: [
            {
              required: true,
              message: '请选择事项分类',
              trigger: 'submit'
            }
          ],
          belongStratumCode: [
            {
              required: true,
              message: '请选择',
              trigger: 'submit'
            }
          ],
          levelCode: [
            {
              required: true,
              message: '请选择',
              trigger: 'submit'
            }
          ],
          fromUnitCode: [
            {
              required: true,
              message: '请选择',
              trigger: 'submit'
            }
          ],
          // toName: [
          //   {
          //     required: true,
          //     message: '请输入',
          //     trigger: 'submit',
          //   },
          //   { max: 50, message: '长度50字符以内', trigger: 'change' },
          // ],
          pursuantShortName: [
            {
              required: true,
              message: '请输入政策依据',
              trigger: 'submit'
            },
            { max: 1000, message: '长度1000字符以内', trigger: 'change' }
          ],
          pursuantFullName: [
            { max: 1000, message: '长度1000字符以内', trigger: 'change' }
          ],
          areaCode: [{ required: true, message: '请选择所属地区' }]
        },
        forms: [
          // {
          //   label: '事项编码',
          //   type: 'input',
          //   span: 12,
          //   prop: 'itemCode'
          // },
          // {
          //   label: '发现方式',
          //   type: 'select',
          //   sels: [],
          //   span: 12,
          //   prop: 'fromCode'
          // },
          {
            label: '事项名称',
            type: 'input',
            span: 24,
            prop: 'itemName'
          },
          {
            label: '事项描述',
            type: 'textarea',
            // maxlength: 200,
            showCount: true,
            span: 24,
            prop: 'descriptions'
          },
          {
            label: '所属层级',
            type: 'slot',
            sels: [],
            // maxlength: 200,
            showCount: true,
            span: 12,
            prop: 'belongStratumCode',
            render: (h, item) => {
              const self = this
              return (
                <c-select
                  disabled={self.levelDisabled}
                  value={self.addForm.model.belongStratumCode}
                  on-change={(val) => {
                    self.addForm.model.belongStratumCode = val
                    self.addForm.model.belongStratumName = item.sels.filter(
                      (i) => i.value == val
                    )[0].label
                  }}
                >
                  {item.sels.map((c) => {
                    return (
                      <c-option
                        key={c.key}
                        label={c.label}
                        value={c.value}
                        disabled={c.disabled}
                      ></c-option>
                    )
                  })}
                </c-select>
              )
            }
          },
          {
            label: '事项等级',
            type: 'sel',
            sels: [],
            // maxlength: 200,
            showCount: true,
            span: 12,
            prop: 'levelCode'
          },
          {
            label: '多跨场景',
            type: 'slot',
            sels: [],
            showCount: true,
            span: 12,
            // clearable: true,
            // disabled: true,
            prop: 'itemSceneId',
            render: (h, item) => {
              const self = this
              return (
                <c-select
                  value={self.addForm.model.itemSceneId}
                  on-change={(val) => {
                    self.addForm.model.itemSceneId = val
                    self.addForm.model.itemSceneName = item.sels.filter(
                      (i) => i.value === val
                    )[0].label
                  }}
                >
                  {item.sels.map((c) => {
                    return (
                      <c-option
                        key={c.key}
                        label={c.label}
                        value={c.value}
                      ></c-option>
                    )
                  })}
                </c-select>
              )
            }
          },
          {
            label: '事项分类',
            type: 'cascader',
            'show-all-levels': true,
            options: [],
            // maxlength: 200,
            children: 'childNode',
            // value: "id",
            // text: "name",
            showCount: true,
            span: 12,
            prop: 'categoryId',
            change: (val) => {
              if (val) {
                const obj = this.categoryList.filter((i) => i.value == val)[0]
                this.addForm.model.categoryCode = obj.categoryCode
                this.addForm.model.categoryId = obj.id
              }
            }
          },
          // {
          //   label: '申请部门',
          //   type: 'cascader',
          //   options: [],
          //   span: 12,
          //   prop: 'fromUnitCode'
          // },
          {
            label: '建议部门',
            type: 'textarea',
            // maxlength: 200,
            showCount: true,
            // placeholder: '请输入建议处置部门',
            span: 24,
            prop: 'adviceDisposeDept'
          },
          {
            label: '政策依据',
            type: 'textarea',
            // maxlength: 200,
            showCount: true,
            span: 24,
            prop: 'pursuantShortName',
            upload: true
          },
          {
            label: '流程描述',
            type: 'textarea',
            // maxlength: 200,
            showCount: true,
            span: 24,
            prop: 'pursuantFullName'
          },
          {
            label: '处置时限',
            type: 'slot',
            maxlength: 200,
            showCount: true,
            span: 12,
            sels: [],
            prop: 'toName',
            render: (h, item) => {
              const self = this
              return (
                <div class="deal-time">
                  <c-input
                    value={self.addForm.model[item.prop]}
                    disabled={item.disabled || false}
                    clearable={item.clearable || true}
                    placeholder="请输入"
                    on-input={(val) => {
                      self.addForm.model[item.prop] = self.changeTime(val)
                    }}
                  ></c-input>
                  <c-select
                    value={self.addForm.model.toCode}
                    on-change={(val) => {
                      self.addForm.model.toCode = val
                    }}
                  >
                    {item.sels.map((c) => {
                      return (
                        <c-option
                          key={c.key}
                          label={c.label}
                          value={c.value}
                        ></c-option>
                      )
                    })}
                  </c-select>
                </div>
              )
            }
          },
          {
            label: '所属地区',
            type: 'cascader',
            span: 12,
            disabled: true,
            prop: 'areaCode',
            options: []
            // maxlength: 200,
          }
        ]
      },
      deptListData: [], // 部门数据
      selfFileList: [],
      districtListData: [], // 行政区划数据
      // form表单options位置start
      LevelNum: 2, // 所属层级
      MatterNum: 3, // 事项等级
      sceneNum: 4, // 多跨场景
      ClassNum: 5, // 事项分类
      TimeNum: 9, // 处置时限
      areaNum: 10, // 所属地区
      // // form表单options位置end
      levelDisabled: false
    }
  },
  props: {
    originData: {
      type: Object,
      default() {
        return {}
      }
    },
    newAdd: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    ...mapGetters(['user'])
  },
  watch: {
    originData: {
      handler() {
        this.copyData()
      },
      deep: true,
      immediate: true
    }
  },
  render(h) {
    const self = this
    return (
      <div class="add-type-wrap my-form-wrap">
        <el-form
          props={{ model: self.addForm.model }}
          rules={self.addForm.rules}
          label-width="90px"
          ref="addForm"
        >
          <el-row>{this.renderLayout(h, this.addForm.forms)}</el-row>
        </el-form>
      </div>
    )
  },
  methods: {
    toStr(arr) {
      arr.forEach((item, index) => (arr[index] = `${item}`))
      return arr
    },
    copyData() {
      // 所属层级申请时默认不可选择
      this.levelDisabled = !this.newAdd
      clearTimeout(this.copyTimer) // 等待选择列表出现
      if (
        !this.addForm.forms[this.ClassNum].options.length ||
        !this.addForm.forms[this.areaNum].options.length
      ) {
        this.copyTimer = setTimeout(() => {
          this.copyData()
        }, 100)
      } else {
        const originData = deepClone(this.originData)
        //
        this.addForm.model = {
          itemCode: originData.itemCode,
          itemName: originData.itemName,
          fromCode: originData.fromCode || this.addForm.model.fromCode,
          descriptions: originData.descriptions,
          categoryCode: originData.categoryCode,
          categoryId: originData.categoryId ? originData.categoryId + '' : '',
          itemSceneId: originData.itemSceneId,
          itemSceneName: originData.itemSceneName,
          belongStratumCode:
            originData.belongStratumCode ||
            this.addForm.model.belongStratumCode,
          belongStratumName:
            originData.belongStratumName ||
            this.addForm.model.belongStratumName,
          levelCode: originData.levelCode || this.addForm.model.levelCode,
          fromUnitCode:
            originData.fromUnitCode || this.addForm.model.fromUnitCode,
          pursuantShortName: originData.pursuantShortName,
          adviceDisposeDept: originData.adviceDisposeDept,
          pursuantFullName: originData.pursuantFullName,
          toCode: originData.toCode || this.addForm.model.toCode,
          toName: originData.toName,
          areaName: originData.areaName || this.addForm.model.areaName, // 用户地区名称
          areaCode: originData.areaCode || this.addForm.model.areaCode, // 用户地区Id
          districtId: originData.districtId || this.addForm.model.districtId,
          fileList: originData.fileList || []
        }
        this.selfFileList = (originData.fileList || []).map((item) => {
          return {
            name: item.fileName,
            url: item.fileUrl,
            ...item
          }
        })
      }
    },
    reset() {
      this.$nextTick(() => {
        this.$refs.addForm.resetFields()
        this.addForm.model = deepClone(this.originForm.model)
        this.selfFileList = []
      })
    },
    handData(model) {
      // 处理申请部门名称
      model.fromUnitName = this.deptListData.find(
        (item) => item.deptCode === model.fromUnitCode
      )?.text
      model.areaName = this.districtListData.find(
        (item) => item.districtNo === model.areaCode
      )?.text
      return model
    },
    getVal() {
      return this.handData(this.addForm.model)
    },
    submit() {
      return this.$refs.addForm.validate().then(
        (res) => {
          return this.handData(this.addForm.model)
        },
        // eslint-disable-next-line
        (err) => {
          this.$emit('validate')
          return false
        }
      )
    },
    cancel() {
      this.addForm.cancel &&
        this.addForm.cancel.call(this.$parent, this.addForm.model)
    },
    renderLayout(h, items) {
      return items.map((item) => {
        const span = item.span || 24
        return (
          <el-col span={span} prop={String(item.prop)}>
            <el-form-item label={item.label} prop={String(item.prop)}>
              {this.renderItem(h, item)}
            </el-form-item>
          </el-col>
        )
      })
    },
    renderItem(h, item) {
      const self = this
      const types = {
        sel: self.renderSelect,
        input: self.renderInput,
        textarea: self.renderTextarea,
        cascader: self.renderCascader,
        slot: self.renderSlot
      }
      return types[item.type](h, item)
    },
    renderInput(h, item) {
      // const self = this
      return (
        <el-input
          vModel={this.addForm.model[item.prop]}
          disabled={item.disabled || false}
          clearable={item.clearable || true}
          placeholder={item.placeholder || ''}
          // on-input={ (val) => { self.inputEvent(val, item) }}
          // on-change={val => this.change(val, item)}
        ></el-input>
      )
    },
    // 每一项的change事件
    change(val, item) {
      this.addForm[item.prop] = item.type === 'in' ? val.trim() : val
      if (item.change) {
        item.change.call(this.$parent, val, item)
      }
    },
    inputEvent(val, item) {
      this.addForm.model[item.prop] = item.trim === true ? val.trim() : val
      if (item.change) {
        item.change()
      }
    },
    renderSelect(h, item) {
      return (
        <c-select
          value={this.addForm.model[item.prop]}
          disabled={item.disabled || false}
          multiple={item.multiple || false}
          collapse-tags={item.collapseTags || false}
          clearable={item.clearable || false}
          on-change={(val) => this.change(val, item)}
          on-input={(val) => (this.addForm.model[item.prop] = val)}
        >
          {this.renderOptions(h, item)}
        </c-select>
      )
    },
    // 渲染选择框的每一项
    renderOptions(c, options) {
      if (options.getList) {
        options.getList().then((data) => {
          options.sels = data
          return data.map((item, index) => {
            return c('elOption', {
              props: {
                key: item.value,
                label: item.label,
                value: item.value,
                disabled: item.disabled || false
              }
            })
          })
        })
      } else {
        return options.sels.map((item, index) => {
          return c('cOption', {
            props: {
              key: item.value,
              label: item.label,
              value: item.value,
              disabled: item.disabled || false
            }
          })
        })
      }
    },
    renderSlot(h, item) {
      return item.render.call(this.$parent, h, item)
    },
    renderCascader(h, item) {
      return (
        <c-cascader
          filterable
          value={this.addForm.model[item.prop]}
          options={item.options}
          disabled={item.disabled || false}
          children="childNode"
          show-all-levels={item['show-all-levels'] || false}
          on-input={(val) => {
            this.addForm.model[item.prop] = val
          }}
          on-change={(val) => item.change && item.change(val)}
          {...{
            attrs: {
              props: {
                checkStrictly: true,
                expandTrigger: 'hover',
                emitPath: false
              }
            }
          }}
        ></c-cascader>
      )
    },
    // 渲染renderTextarea
    renderTextarea(h, item) {
      const self = this
      return (
        <div>
          <c-input
            type="textarea"
            disabled={item.disabled || false}
            on-input={(val) => {
              self.inputEvent(val, item)
            }}
            placeholder={item.placeholder || ''}
            maxlength={item.maxlength}
            rows={item.row || 2}
            minlength={item.minlength}
            clearable={item.clearable}
            show-word-limit={item.showCount}
            value={self.addForm.model[item.prop]}
          ></c-input>
          {item.upload && (
            <el-upload
              ref="uploadFile"
              style="margin-top: 6px"
              action="/api/sys/file/upload"
              multiple
              before-upload={self.fileJudge}
              {...{
                props: {
                  'on-exceed': self.handleExceed,
                  'on-success': self.handleUploadSuccess,
                  'on-remove': self.handleFileRemove,
                  'on-change': self.handleUploadErr,
                  'on-error': self.handleError
                }
              }}
              accept=".doc,.docx,.pdf"
              limit={5}
              file-list={self.selfFileList}
            >
              <c-button size="small" plain>
                <i class="el-icon-plus"></i>上传附件
              </c-button>
              <span style="margin-left: 10px" slot="tip">
                可上传.doc、.docx、.pdf格式的文件
              </span>
            </el-upload>
          )}
        </div>
      )
    },
    fileJudge(file) {
      if (file && file.size / 1024 / 1204 > 10) {
        this.$message({
          type: 'warning',
          message: '上传文件超过最大限制 10 M',
          customClass: 'mz-index'
        })
        return false
      }
    },
    handleFileRemove(file, fileList) {
      this.addForm.model.fileList = deepClone(fileList)
    },
    handleUploadSuccess(res, file, fileList) {
      if (res.success) {
        const obj = {
          fileUrl: res.data.url,
          fileName: file.name
        }
        this.addForm.model.fileList.push(obj)
      } else {
        let idx = fileList.findIndex((item) => item.uid === file.uid)
        this.$refs.uploadFile.uploadFiles.splice(idx, 1)
        this.$message({
          type: 'error',
          message: res.message,
          customClass: 'mz-index'
        })
      }
    },
    // 上传失败
    handleError() {
      this.$message({
        type: 'error',
        message: '文件上传失败',
        customClass: 'mz-index'
      })
    },
    handleUploadErr(err, file) {
      // console.log(err, file)
      // console.log('文件改变:', this.addForm.model.fileList)
    },
    //
    handleExceed(files, fileList) {
      this.$message({
        type: 'warning',
        message: '最多可上传5个文件，已超过限制',
        customClass: 'mz-index'
      })
    },
    setText(data, num = 1) {
      const result = data
      const transform = function (from, to) {
        result.forEach((item) => {
          item[to] = item[from]
        })
        return result
      }
      function cal(from, to) {
        transform(from, to)
        if ((num -= 1) === 0) {
          return result
        } else {
          return cal
        }
      }
      return cal
    },
    // 获取发现方式字典表
    async getFindMethod() {
      const data = await getDictByType('FIND_WAY')
      if (!data.success) {
        this.$message({
          message: data.message,
          type: 'error'
        })
      }
      const result = this.setText(data.data, 2)('codeName', 'label')(
        'codeValue',
        'value'
      )
      this.addForm.forms[1].sels = result
    },
    changeStr(result) {
      result.forEach((item) => {
        item.value = `${item.value}`
        if (item.children && Array.isArray(item.children)) {
          this.changeStr(item.children)
        }
      })
    },
    // 获取所属层级字典表
    async getBelongStratum() {
      const data = await getDictByType('ITEM_STRATUM_LEVEL')
      if (this.dealReturn(data)) {
        const result = this.setText(data.data, 2)('codeName', 'label')(
          'codeValue',
          'value'
        )
        if (this.newAdd) {
          const { poltype } = this.$store.getters.user
          result.forEach((el) => {
            if (el.codeValue < poltype) {
              el.disabled = true
            }
          })
        }
        this.addForm.forms[this.LevelNum].sels = result
        // if (this.addForm.model.belongStratumCode) {
        //   this.addForm.model.belongStratumName = result.filter(
        //     (i) => i.value == this.addForm.model.belongStratumCode
        //   )[0].label
        // }
      }
    },
    // 获取事项分类字典表
    async getType() {
      const { districtNo: areaCode, districtId: areaId } = this.user
      const data = await this.$get({
        url: `/onm/event/type/info/uphold/getAllCategory?areaCode=${areaCode}&areaId=${areaId}`
      })
      if (this.dealReturn(data)) {
        const result = data.data
        deepTree(result)
        this.changeStr(result)
        this.addForm.forms[this.ClassNum].options = result
        treeToList(result, this.categoryList)
      }
    },
    // 查询多跨场景
    async getBelongToArea() {
      const { districtNo, districtId } = this.user
      // const data = await getDictByType('MENU_FIELD')
      const params = {
        areaCode: districtNo,
        areaId: districtId
      }
      const { data } = await getSceneList(params)
      const result = this.setText(data, 2)('name', 'label')('id', 'value')
      this.addForm.forms[this.sceneNum].sels = result
    },
    // 获取事件等级字典表
    async getLevel() {
      const data = await getDictByType('EVENT_LEVEL')
      if (this.dealReturn(data)) {
        const result = this.setText(data.data, 2)('codeName', 'label')(
          'codeValue',
          'value'
        )
        // console.log('事项登记', result)
        this.addForm.forms[this.MatterNum].sels = result
      }
    },
    // 获取部门
    async getDept() {
      const data = await this.$get({
        url: '/sys/deptment/findNextChildNodeTreeAll'
      })
      if (this.dealReturn(data)) {
        const result = data.data
        deepTree(result, 'deptCode')
        // this.addForm.forms[7].options = result
        treeToList(result, this.deptListData)
        const { deptCode } = this.user
        this.originForm.model.fromUnitCode = deptCode
        this.addForm.model.fromUnitCode = deptCode
      }
    },
    async getDistrictTree() {
      const { data } = await getDistrictTree()
      deepTree(data, 'districtNo')
      treeToList(data, this.districtListData)
      this.addForm.forms[this.areaNum].options = data
    },
    // 获取处置时限
    async getTime() {
      const data = await getDictByType('DISPOSAL_TIME_LIMIT')
      if (this.dealReturn(data)) {
        const result = this.setText(data.data, 2)('codeName', 'label')(
          'codeValue',
          'value'
        )
        const ind = result.findIndex((el) => {
          return el.codeValue === '3'
        })
        if (ind !== -1) {
          result.splice(ind, 1)
        }
        this.addForm.forms[this.TimeNum].sels = result
      }
    },
    // 处理接口返回值
    dealReturn(data) {
      if (!data.success) {
        this.$message({
          message: data.message,
          type: 'error'
        })
        return false
      }
      return true
    },
    // 输入时间
    changeTime(val) {
      // const MaxNumber = 99;
      let pval = ''
      pval = val.replace(/^\./g, '') // 必须保证第一个为数字而不是.
      pval = pval.replace(/[^\d.]/g, '')
      pval = pval.replace(/\.{2,}/g, '.') // 只保留第一个. 清除多余的
      pval = pval.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.') // 不能重复出现点
      pval = pval.replace(/^(\-)*(\d+)\.(\d).*$/, '$1$2.$3') // 只能输入1个小数
      let len1 = pval.substr(0, 1)
      let len2 = pval.substr(1, 1)
      // 如果第一位是0，第二位不是点，就用数字把点替换掉
      if (pval.length > 1 && len1 === '0' && len2 !== '.') {
        pval = pval.substr(1)
      }
      // let n = pval.indexOf(".");
      // if (n !== -1 && pval.split(".")[0] == MaxNumber) {
      //   pval = MaxNumber;
      // }
      // if (pval > MaxNumber) {
      //   pval = pval.slice(0, -1);
      // }
      return pval
    }
  },
  created() {
    // this.getFindMethod()
    this.getType()
    this.getLevel()
    this.getBelongToArea() // 场景
    this.getTime()
    this.getDept()
    this.getDistrictTree()
    this.getBelongStratum()
  }
}
</script>

<style lang='scss'>
.add-type-wrap {
  margin: 0 auto;
  .el-select,
  .el-cascader {
    width: 100%;
  }
  .deal-time {
    width: 100%;
    display: flex;
    .el-select {
      width: 90px;
    }
    .el-input {
      flex: 1;
    }
  }
}
</style>
